fix(moe_vec): chunk launches when tokens*top_k exceeds gridDim.z limit - #125
Open
BruceLoveDecimal wants to merge 1 commit into
Open
fix(moe_vec): chunk launches when tokens*top_k exceeds gridDim.z limit#125BruceLoveDecimal wants to merge 1 commit into
BruceLoveDecimal wants to merge 1 commit into
Conversation
The MMVQ MoE kernels put tokens*top_k in grid dimension z, which is capped at 65535 by CUDA. Profile/dummy runs with large batched token counts (e.g. 8192 tokens x top_k 8 = 65536) exceeded this and crashed with CUDA invalid argument during engine init on Hy3 IQ1_M. Split the launch into per-token-range chunks like quantize_row_q8_1_cuda already does, and add test_moe_large_batch covering tokens*top_k > 65535.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The MMVQ MoE kernels in
csrc/gguf/moe_vec.cuhplacetokens * top_kin thez dimension of the launch grid:
gridDim.zis hardware-capped at 65535. vLLM's defaultmax_num_batched_tokensis 8192, so any MMVQ-path MoE model withtop_k >= 8hits
8192 * 8 = 65536 > 65535insideprofile_runand the engine diesduring startup with:
This was found while integrating the Hy3 (Hunyuan) architecture (#88), whose
IQ1_M experts (top_k 8) hit this limit in
profile_runon every startup.This is 100% reproducible on startup for such models with default settings —
it is not a load-dependent or intermittent failure. Decode-time batches are
small, so the limit is only reachable through the profile/dummy run or large
prefill batches.
The vec path is selected when both expert weight types are in
MMVQ_QUANT_TYPESbut not on the MMQ gemm path(
quantization/fused_moe.py), which in practice means i-matrix (IQ*) quants —the formats commonly used for large MoE GGUFs.
Fix
Split the launch into per-token-range chunks so each launch keeps
gridDim.z <= 65535, mirroring the existing chunking pattern inquantize_row_q8_1_cuda(gguf_kernel.cu):Chunk boundaries align to whole tokens (multiples of
top_kin grid z), andthe
vy/dst/topk_idspointers are offset accordingly, so kernelindexing is unchanged. Single-launch cases take the same path as before with
one iteration.
The 19 per-type launcher bodies were byte-identical except for template
arguments, so they are consolidated into one
MOE_VEC_Q8_1_LAUNCHERmacro(429 → 158 lines) while touching the launch logic.
Test Plan / Test Result
New regression test
test_moe_large_batchexercises the chunked launch pathdirectly:
num_tokens=9000, top_k=8gives9000 * 8 = 72000 > 65535, whichcrashed with
CUDA error: invalid argumentbefore the fix. It runs for bothIQ1_M(the motivating i-matrix case) andQ4_0, and compares against thedequantized
fused_expertsreference.Full run on an RTX PRO 6000 Blackwell (sm_120), torch 2.13.0+cu130, CUDA 13
toolchain, vLLM 0.27.0:
The 68 failures are all
test_moe[*-dtype2-...]cases failing inside thetriton reference kernel with
OutOfResources: shared memory, Required: 122880, Hardware limit: 101376— a hardware/triton limitation of this GPU unrelatedto the change. The identical failure set (same test IDs, same error) exists in
the baseline run on the parent commit recorded before this branch
(
69 failedthere = the same 68 kernel cases plus one unrelatedtest_plugin.pyordering flake that passes in isolation and passes here).ruff checkon the full repo also passes.